use gloo_net::http::Request;
use serde::Deserialize;
use serde_json::json;

use super::APP_HOST;

#[derive(Deserialize, Clone, PartialEq)]
pub struct Rustacean {
  pub id: i32,
  pub name: String,
  pub email: String,
  pub created_at: String,
}

pub async fn api_rustaceans(
  token: &str,
) -> Result<Vec<Rustacean>, gloo_net::Error> {
  let request_url = format!("{}/rustaceans", APP_HOST);

  let resp = Request::get(&request_url)
    .header("Authorization", &format!("Bearer {}", token))
    .send()
    .await?;

  resp.json::<Vec<Rustacean>>().await
}

pub async fn api_rustacean_show(
  token: &str,
  id: i32,
) -> Result<Rustacean, gloo_net::Error> {
  let request_url = format!("{}/rustaceans/{}", APP_HOST, id);

  let resp = Request::get(&request_url)
    .header("Authorization", &format!("Bearer {}", token))
    .send()
    .await?;

  resp.json::<Rustacean>().await
}

pub async fn api_rustacean_create(
  token: &str,
  name: String,
  email: String,
) -> Result<Rustacean, gloo_net::Error> {
  let request_url = format!("{}/rustacean", APP_HOST);

  let resp = Request::post(&request_url)
    .header("Authorization", &format!("Bearer {}", token))
    .json(&json!({
      "name": name,
      "email": email
    }))?
    .send()
    .await?;

  resp.json::<Rustacean>().await
}

pub async fn api_rustacean_update(
  token: &str,
  id: i32,
  name: String,
  email: String,
) -> Result<Rustacean, gloo_net::Error> {
  let request_url = format!("{}/rustaceans/{}", APP_HOST, id);

  let resp = Request::put(&request_url)
    .header("Authorization", &format!("Bearer {}", token))
    .json(&json!({
      "name": name,
      "email": email
    }))?
    .send()
    .await?;

  resp.json::<Rustacean>().await
}

pub async fn api_rustacean_delete(
  token: &str,
  id: i32,
) -> Result<(), gloo_net::Error> {
  let request_url = format!("{}/rustaceans/{}", APP_HOST, id);

  Request::delete(&request_url)
    .header("Authorization", &format!("Bearer {}", token))
    .send()
    .await?;

  Ok(())
}
